package x.y.z;

import org.junit.Test;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.IntBinaryOperator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class StreamApi {
    @Test
    public void test1() {

        List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8);
        List<Integer> twoEvenSquares =
                numbers.stream()
                        .filter(n -> {
                            System.out.println("filtering " + n);
                            return n % 2 == 0;
                        })
                        .map(n -> {
                            System.out.println("mapping " + n);
                            return n * n;
                        })
                        .limit(2)
                        .collect(Collectors.toList());
        twoEvenSquares.forEach(integer -> System.out.println(integer.intValue()));
    }

    @Test
    public void test2() {
        List<String> words = Arrays.asList("Oracle", "Java", "Magazine");
        List<Integer> wordLengths =
                words.stream()
                        .map(String::length)
                        .collect(Collectors.toList());
        wordLengths.forEach(integer -> System.out.println(integer.intValue()));
    }

    @Test
    public void test3() {
        // range: [)
        // rangeClosed: []
        IntStream.rangeClosed(10, 30).filter(n -> n % 2 == 0).forEach(System.out::println);
    }

    @Test
    public void test4(){
        System.out.println(IntStream.rangeClosed(10,30).sum());
        IntStream.rangeClosed(10,30).reduce(Integer::sum).ifPresent(System.out::println);
        System.out.println(IntStream.rangeClosed(10,30).reduce(1,Integer::max));
        IntStream.rangeClosed(10,30).max().ifPresent(System.out::println);
        IntStream.rangeClosed(10,30).min().ifPresent(System.out::println);
    }

    @Test
    public void test5(){
        Stream.of(1, 2, 3, 4).forEach(System.out::println);
        int[] numbers = {1, 2, 3, 4};
        Arrays.stream(numbers).forEach(System.out::println);
    }

    @Test
    public void test6(){
        Stream.iterate(0, n -> n + 10).limit(10).forEach(System.out::println);
    }

    @Test
    public void test7(){
        Stream<String> words = Stream.of("Java", "Magazine", "is",
                "the", "best");

        Map<String, Long> letterToCount =
                words.map(w -> w.split(""))
                        .flatMap(Arrays::stream)
                        .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
        for (Map.Entry<String,Long> entry:letterToCount.entrySet()){
            System.out.println(entry.getKey()+":"+entry.getValue());
        }
    }

    @Test
    public void test8() throws IOException {
        Files.lines(Paths.get("D:\\Projects\\Java\\JavaGrammer\\src\\x\\y\\z\\stuff.txt"))
                .map(line -> line.split("\\s+")) // Stream<String[]>
                .map(Arrays::stream) // Stream<Stream<String>>
                .distinct() // Stream<Stream<String>>
                .forEach(System.out::println);
    }

    @Test
    public void test9() throws IOException {
        Files.lines(Paths.get("D:\\Projects\\Java\\JavaGrammer\\src\\x\\y\\z\\stuff.txt"))
                .map(line -> line.split("\\s+")) // Stream<String[]>
                .flatMap(Arrays::stream) // Stream<String>
                .distinct() // Stream<String>
                .forEach(System.out::println);
    }
}
